home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Freeware 1998 June
/
SGI Freeware 1998 June.iso
/
dist
/
fw_UMINNgopher.idb
/
usr
/
freeware
/
src
/
gopher_1.12
/
gopher
/
manager.c.z
/
manager.c
Wrap
C/C++ Source or Header
|
1997-09-09
|
11KB
|
468 lines
/********************************************************************
* $Author: drich $
* $Revision: 1.1 $
* $Date: 1995/10/03 04:08:12 $
* $Source: /proj/freeware1.0/gopher1.12/src/gopher/RCS/manager.c,v $
* $State: Exp $
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: manager.c
* Procedures to manage the screen.
*********************************************************************
* Revision History:
* $Log: manager.c,v $
* Revision 1.1 1995/10/03 04:08:12 drich
* gopher 1.2 check-in
*
* Revision 1.3 1993/01/06 21:01:40 lindner
* Improved behaviour when executing an item by typing it's number
* The arrow and screen are updated to reflect the item being
* retrieved.
*
* Revision 1.2 1993/01/05 22:31:57 lindner
* Fixed display problems with directory title searching.
*
* Revision 1.1 1992/12/10 23:32:16 lindner
* gopher 1.1 release
*
* Revision 1.1 1992/12/10 06:16:51 lindner
* Initial revision
*
*
*********************************************************************/
#include "gopher.h"
#define MENULINE(x) (x)+3
/* If any gophers to display (screen can be blank), count the number
of pages. If there is a remainder greater than zero, add one page */
#define PAGECALC(x,y) (y) ? (x/y) + ((x%y)>0) : 1
/*
** Draw the title on the top
*/
void
Draw_Banner()
{
standout();
CURcenterline(CursesScreen,VERSIONline, 0);
standend();
}
/*
** Draw the status line
*/
void
Draw_Status(textline)
char *textline;
{
move(LINES-1, 0);
clrtoeol();
mvaddstr(LINES-1, 0, "Press ");
standout();
addstr("?");
standend();
addstr(" for Help, ");
standout();
addstr("q");
standend();
addstr(" to Quit, ");
standout();
addstr("u");
standend();
addstr(" to go up a menu");
clrtoeol();
mvaddch(LINES-1, COLS-strlen(textline)-2, ' ');
addstr(textline);
}
/*
** Man is this ugly.
*/
void
Display_Dir_Page(gopherdir, iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen)
GopherDirObj *gopherdir;
int iNewLine;
int nNewPage, nMaxPages, iPageLen, iLastPageLen;
{
int i, iLoop, iOffset;
char temp[1024];
char *c, *d;
int m, n, type, max;
/*** Clear the screen and redraw the top line **/
clear();
Draw_Banner();
/** Draw the menu **/
iLoop = (nNewPage == nMaxPages) && iLastPageLen ? iLastPageLen : iPageLen;
for (i= 0, iOffset = (nNewPage-1) * iPageLen; i <iLoop; i++, iOffset++) {
move(MENULINE(i+1), 6);
printw("%d.", iOffset +1);
if (iOffset + 1 < 10)
addch(' ');
type = GSgetType(GDgetEntry(gopherdir,iOffset));
d = GSgetTitle(GDgetEntry(gopherdir,iOffset));
max = COLS - 13;
switch(type)
{
case A_DIRECTORY:
case A_FILE:
max--;
break;
case A_SOUND:
max -= 3;
break;
case A_INDEX:
max -=4;
break;
case A_CSO:
case A_TN3270:
case A_TELNET:
case A_UNIXBIN:
case A_MACHEX:
max -=6;
break;
case A_PCBIN:
max -=9;
break;
case A_GIF:
case A_IMAGE:
max -= 10;
break;
}
if((m = strlen(d)) <= max)
printw(" %s", d);
else {
/*** Cut out the middle bits **/
if ((c = strchr(d, '/'))!=NULL && (max > (c-d))) {
n = c - d;
strncpy(temp, d, n);
strcpy(temp + n, "..");
strcat(temp, d + (m + n - max));
printw(" %s", temp);
} else {
/** Trunc it.. **/
strcpy(temp, d);
temp[max] ='\0';
printw(" %s..", temp);
}
}
switch(type)
{
case A_DIRECTORY:
addch('/');
break;
case A_CSO:
addstr(" <CSO>");
break;
case A_TN3270:
addstr(" <3270>");
break;
case A_TELNET:
addstr(" <TEL>");
break;
case A_INDEX:
addstr(" <?>");
break;
case A_SOUND:
addstr(" <)"); /** It's supposed to look like a speaker! **/
break;
case A_FILE:
addch('.');
break;
case A_PCBIN:
addstr(" <PC Bin>");
break;
case A_UNIXBIN:
addstr(" <Bin>");
break;
case A_IMAGE:
case A_GIF:
addstr(" <Picture>");
break;
case A_MACHEX:
addstr(" <HQX>");
break;
}
}
}
/* scline - Screen line relocator.
* Returns the line resulting from choice */
int
scline( iOldGopher, iNewGopher, gophersdir)
int iOldGopher; /* Which gopher previously displayed */
int iNewGopher; /* New gopher to be displayed */
GopherDirObj *gophersdir;
{
int iPageLen, iLastPageLen; /* Length of normal, final pages */
int nMaxPages, nNewPage, nOldPage; /* Natural numbers */
int iOldLine, iNewLine; /* Screen locations */
char sPagenum[40];
int iMaxGophers;
iMaxGophers = GDgetNumitems(gophersdir);
if (iNewGopher==0)
iNewGopher = GDgetNumitems(gophersdir);
if ((iNewGopher > iMaxGophers))
iNewGopher = 1;
iPageLen = LINES-6; /* Number of menu lines possible per page */
nMaxPages = PAGECALC(iMaxGophers, iPageLen); /* Total number of pages */
nOldPage = PAGECALC(iOldGopher, iPageLen);
nNewPage = PAGECALC(iNewGopher, iPageLen);
if ((nNewPage < 1) || (nNewPage > nMaxPages)) /* It won't work , make*/
return(iOldGopher); /* no changes */
iLastPageLen = iMaxGophers % iPageLen;
/* Lines on last page */
iOldLine = iOldGopher - ((nOldPage-1)*iPageLen);/* Old Screen location */
iNewLine = iNewGopher - ((nNewPage-1)*iPageLen);/* New Screen location */
if ((iNewLine < 0) || (iNewLine > iPageLen))
return(iOldGopher);
if (nOldPage != nNewPage) {
Display_Dir_Page(gophersdir,
iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen);
CURcenterline(CursesScreen,GDgetTitle(gophersdir), 2); /*** Draw the title ***/
}
sprintf(sPagenum, " Page: %d/%d", nNewPage, nMaxPages);
Draw_Status(sPagenum);
mvaddstr(MENULINE(iOldLine), 1, " ");
mvaddstr(MENULINE(iNewLine), 1, "-->");
refresh();
return(iNewGopher);
}
/*
** This routine draws a numbered menu
** from a gopherdirobj
**
** It returns the number that the user selected, or it returns
** zero if the user decided to cancel.
**
*/
int GetMenu(gd, typedchar, redisplay)
GopherDirObj *gd; /** where the items are **/
int *typedchar;
boolean redisplay;
{
int ch; /* Input character */
int iItem; /* Display line */
static int iNewItem=1;
char sLinenum[5]; /* Used when going to a specific line */
BOOLEAN menudone = FALSE;
int numitems;
/** variables for searching **/
char search1[100];
char *search2;
int sfound;
int i;
search1[0] = '\0'; /* search string will be remembered so init now */
numitems = GDgetNumitems(gd);
iItem = -1;
iNewItem = GDgetCurrentItem(gd);
if (redisplay == TRUE) {
iItem = scline(iItem, iNewItem, gd);
/*** Draw the title ***/
CURcenterline(CursesScreen,GDgetTitle(gd), 2);
move(3+iNewItem,4);
/* Move to the last line that we were sitting on */
refresh();
} else
iItem = GDgetCurrentItem(gd);
while (menudone == FALSE) {
ch = CURgetch(CursesScreen);
switch(ch)
{
case 'j':
case '\016':
case KEY_DOWN:
iNewItem = iItem + 1; /* Advance down the page */
break;
case 'k':
case '\020': /*** For those emacs dudes **/
case KEY_UP:
iNewItem = iItem - 1; /* Back up */
break;
case '+': /** Like in elm **/
case '>': /** Like in nn **/
case ' ': /** Like in the pager ***/
case KEY_NPAGE:
/*** Go down a page ***/
iNewItem = iItem + (LINES -6);
if (iNewItem > numitems)
iNewItem = numitems;
break;
case '-':
case '<':
case KEY_PPAGE:
case 'b': /*** Like in the pager ***/
/*** Go up a page ***/
iNewItem = iItem - (LINES - 6);
if ( iNewItem < 0 )
iNewItem = 1;
break;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0':
sLinenum[0] = (char) ch;
sLinenum[1] = '\0';
if (CUROldGetOneOption(CursesScreen, "View item number: ", sLinenum) <0) {
scline(iItem, iNewItem, gd);
break;
}
if (atoi(sLinenum) <= numitems)
iNewItem = atoi(sLinenum); /* Jump */
else {
CURBeep(CursesScreen);
break;
}
scline(-1, iNewItem, gd);
if (iNewItem > 0 && iNewItem <= GDgetNumitems(gd)) {
*typedchar = '\n';
GDsetCurrentItem(gd, iNewItem);
return(iItem);
}
break;
case '/':
case 'n':
sfound = 0;
if (search1[0] == '\0' && ch == 'n') {
CursesErrorMsg("Use '/' to define a search first...");
iItem = scline(-1,iItem, gd);
break;
}
if (search1[0] == '\0' || ch == '/')
if (CURGetOneOption(CursesScreen, "Search directory titles for", search1)<0) {
iItem = scline(-1,iItem, gd);
break;
}
if (strlen(search1) == 0) {
iItem = scline(-1, iItem, gd);
break;
}
/*
* Start searching from next item
*/
for (i=iItem; i < numitems && sfound==0; i++) {
search2 = GSgetTitle(GDgetEntry(gd, i));
if (strcasestr(search2, search1) != NULL ) {
iNewItem = i+1;
sfound = 1;
}
}
/* if it wasn't found after the current line start
from the beginning again
*/
for ( i= 0 ; i < iItem && sfound==0;i++) {
search2 = GSgetTitle(GDgetEntry(gd,i));
if (strcasestr(search2,search1) != NULL ) {
iNewItem = i+1;
sfound = 1;
}
}
if (sfound == 0) {
search1[0] = '\0';
CURBeep(CursesScreen);
CursesErrorMsg("Search failed...");
}
if (ch != 'n')
iItem = scline(-1, iNewItem, gd);
break;
case '\0':
break;
default:
menudone = TRUE;
if (ch == KEY_LEFT || ch == 'h' || ch == '\002')
ch = 'u';
if (ch == KEY_RIGHT || ch == 'l' || ch == '\006')
ch = '\n';
*typedchar = ch;
GDsetCurrentItem(gd, iItem);
return(iItem);
}
iItem = scline(iItem, iNewItem, gd);
refresh();
}
*typedchar = ch;
GDsetCurrentItem(gd, iItem);
return(iItem);
}